home *** CD-ROM | disk | FTP | other *** search
- // ------------------------------- //
- // -------- Start of File -------- //
- // ------------------------------- //
- // ----------------------------------------------------------- //
- // C++ Source Code File Name: main.cpp
- // Compiler Used: MSVC40, DJGPP 2.7.2.1, GCC 2.7.2.1, HP CPP 10.24
- // Produced By: Doug Gaer
- // File Creation Date: 09/18/1997
- // Date Last Modified: 03/18/1999
- // Copyright (c) 1997 Douglas M. Gaer
- // ----------------------------------------------------------- //
- // ------------- Program Description and Details ------------- //
- // ----------------------------------------------------------- //
- /*
- The VBD C++ classes are copyright (c) 1997, by Douglas M. Gaer.
- All those who put this code or its derivatives in a commercial
- product MUST mention this copyright in their documentation for
- users of the products in which this code or its derivative
- classes are used. Otherwise, you have the freedom to redistribute
- verbatim copies of this source code, adapt it to your specific
- needs, or improve the code and release your improvements to the
- public provided that the modified files carry prominent notices
- stating that you changed the files and the date of any change.
-
- THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
- THE ENTIRE RISK OF THE QUALITY AND PERFORMANCE OF THIS SOFTWARE
- IS WITH YOU. SHOULD ANY ELEMENT OF THIS SOFTWARE PROVE DEFECTIVE,
- YOU WILL ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR
- CORRECTION.
-
- This is a test program used to test the (P)ersistent base class
- in a practical database application.
- */
- // ----------------------------------------------------------- //
-
- #include <fstream.h> // Using ofstream to print to a text file
- #include <ctype.h>
- #include "grocery.h"
- #include "terminal.h"
- #include "config.h"
- #include "timer.h"
- #include "strutil.h"
- #include "asprint.h"
- #include "pscript.h"
- #include "version.h"
- #include "groc_sh.h"
- #include "dbconfig.h"
- #include "vbdstats.h"
- #include "btwalker.h"
-
- static POD *DB; // Global database pointer
- const int KeyBuf = 25; // Users input limit per string
- const int CBuf = 81; // Input limit for comments
- const char *WildCard = "*"; // Used for wild card searches
- const int retrys = 3; // Times to retry user input operations
- const int StringOffset = 15; // Display output limit per string
- const int IntOffset = 8; // Display output limit per number
-
- // Define configurable parameters
- int CacheSize = 15; // Memory cache size for the index file
- int AdminRights = 1; // Define user privileges
-
- // Define file access modes used in the application
- VBDFile::AccessMode RWMode = VBDFile::READWRITE;
- VBDFile::AccessMode ROMode = VBDFile::READONLY;
-
- // Menu menu setup
- typedef void (*MMF) (); // Pointer to (M)ain (M)enu (F)unctions
- const int MMSelections = 5; // Main menu selections
-
- // Main menu functions
- void Exit();
- void ISRMenu(); // Insertion/Removal menu
- void FindMenu(); // Query menu
- void DisplayMenu(); // Display menu
- void FileMenu(); // File operations menu
-
- const char *mainmenu[MMSelections] = {
- "(0) - Exit this program",
- "(1) - Add, Remove, or Change items in the database",
- "(2) - Find items in the database",
- "(3) - Display items in the database",
- "(4) - File Operations",
- };
-
- MMF MMFunctions[MMSelections] = {
- &Exit,
- &ISRMenu,
- &FindMenu,
- &DisplayMenu,
- &FileMenu,
- };
-
- // Insertion/Removal menu setup
- typedef void (*ISRMF) (); // Pointer to (A)dd (M)enu (F)unctions
- const char *ISRMTitle = "--------- DATABASE INSERTION/REMOVAL MENU ---------";
- const int ISRMSelections = 4; // Insertion/Removal menu selections
-
- // Insertion/Removal menu functions
- void Return();
- void Add();
- void Change();
- void Remove();
-
- const char *isrmenu[ISRMSelections] = {
- "(0) - Return to main menu",
- "(1) - Add items to the database",
- "(2) - Change an item in the database",
- "(3) - Remove an item from the database"
- };
-
- ISRMF ISRMFunctions[ISRMSelections] = {
- &Return,
- &Add,
- &Change,
- &Remove
- };
-
- // Find menu setup
- typedef void (*FMF) (); // Pointer to (F)ind (M)enu (F)unctions
- const char *FMTitle = "---------- DATABASE QUERY MENU ----------";
- const int FMSelections = 4; // Find menu selections
-
- // Find menu functions
- void Return();
- void FindByName();
- void FindByBrand();
- void FindByStore();
-
- const char *findmenu[FMSelections] = {
- "(0) - Return to main menu",
- "(1) - Find objects by Item Name",
- "(2) - Find objects by Brand",
- "(3) - Find objects by Store",
- };
-
- FMF FMFunctions[FMSelections] = {
- &Return,
- &FindByName,
- &FindByBrand,
- &FindByStore,
- };
-
- // Display menu setup
- typedef void (*DMF) (); // Pointer to (D)isplay (M)enu (F)unctions
- const char *DMTitle = "---------- DATABASE DISPLAY MENU ----------";
- const int DMSelections = 3; // Display menu selections
-
- // Display menu functions
- void DisplayLBL(); // Display all objects line by line
- void DisplayAll(); // Display all objects one at a time
-
- const char *displaymenu[DMSelections] = {
- "(0) - Return to main menu",
- "(1) - Display all items line by line",
- "(2) - Display all items one a time"
- };
-
- DMF DMFunctions[DMSelections] = {
- &Return,
- &DisplayLBL,
- &DisplayAll
- };
-
- // File operations menu setup
- typedef void (*FOMF) (); // Pointer to (F)ile (M)enu (F)unctions
- const char *FOMTitle = "---------- DATABASE FILE OPERATIONS MENU ----------";
- const int FOMSelections = 2; // File operations menu selections
-
- // File operations menu functions
- void FileStats();
-
- const char *filemenu[FOMSelections] = {
- "(0) - Return to main menu",
- "(1) - Display Variable Block Database statistics"
- };
-
- FOMF FOMFunctions[FOMSelections] = {
- &Return,
- &FileStats
- };
-
- // Function prototypes for functions use by all menu functions
- void AddObject(Grocery &grocery, Coords *p);
- void ChangeObject(Grocery &grocery, Coords *p, int adding = 0);
- void DisplayObject(Grocery &grocery, Coords *p);
- void LineByLine(Grocery &grocery, Coords *p);
- void DisplayString(const char *s);
- int LoadIndexKeys();
-
- // Search functions
- void FindBy(const char *MemberName, GrocDBItem item);
- void GrocDBSearch(Grocery &grocery, GrocDBItem item, UString &str,
- Coords *p, const char *wildcard = 0);
-
- void MainMenu()
- {
- int c;
- Coords *p = new Coords(0, 0);
-
- while(1) {
- p->SetXY(0, 0);
- p->SetX(terminal->Center(MMTitle));
- p->SetY(terminal->ScreenCenter(MMSelections));
- terminal->ClearScreen();
- terminal->Write(MMTitle, p->XPos(), p->YPrev());
-
- for(int i = 0; i < MMSelections; i++)
- terminal->Write(mainmenu[i], p->XPos(), p->YOffset(1));
-
- terminal->Write("Press the number of your selection >",
- p->XPos(), p->YOffset(2));
-
- c = terminal->GetChar();
- switch(tolower(c)) {
- case '0':
- (*MMFunctions[0]) (); // Call the appropriate menu function
- return;
- case '1':
- (*MMFunctions[1]) (); // Call the appropriate menu function
- break;
- case '2':
- (*MMFunctions[2]) (); // Call the appropriate menu function
- break;
- case '3':
- (*MMFunctions[3]) (); // Call the appropriate menu function
- break;
- case '4':
- (*MMFunctions[4]) (); // Call the appropriate menu function
- break;
- default:
- break;
- }
- }
- }
-
- void ISRMenu()
- {
- int c;
- Coords *p = new Coords(0, 0);
-
- while(1) {
- p->SetXY(0, 0);
- p->SetX(terminal->Center(ISRMTitle));
- p->SetY(terminal->ScreenCenter(ISRMSelections));
- terminal->ClearScreen();
- terminal->Write(ISRMTitle, p->XPos(), p->YPrev());
-
- for(int i = 0; i < ISRMSelections; i++)
- terminal->Write(isrmenu[i], p->XPos(), p->YOffset(1));
-
- terminal->Write("Press the number of your selection >",
- p->XPos(), p->YOffset(2));
-
- c = terminal->GetChar();
- switch(tolower(c)) {
- case '0':
- (*ISRMFunctions[0]) (); // Call the appropriate menu function
- return;
- case '1':
- (*ISRMFunctions[1]) (); // Call the appropriate menu function
- break;
- case '2':
- (*ISRMFunctions[2]) (); // Call the appropriate menu function
- break;
- case '3':
- (*ISRMFunctions[3]) (); // Call the appropriate menu function
- break;
- case '4':
- (*ISRMFunctions[4]) (); // Call the appropriate menu function
- break;
- default:
- break;
- }
- }
- }
-
- void FindMenu()
- {
- int c;
- Coords *p = new Coords(0, 0);
-
- while(1) {
- p->SetXY(0, 0);
- p->SetX(terminal->Center(FMTitle));
- p->SetY(terminal->ScreenCenter(FMSelections));
- terminal->ClearScreen();
- terminal->Write(FMTitle, p->XPos(), p->YPrev());
-
- for(int i = 0; i < FMSelections; i++)
- terminal->Write(findmenu[i], p->XPos(), p->YOffset(1));
-
- terminal->Write("Press the number of your selection >",
- p->XPos(), p->YOffset(2));
-
- c = terminal->GetChar();
- switch(tolower(c)) {
- case '0':
- (*FMFunctions[0]) (); // Call the appropriate menu function
- return;
- case '1':
- (*FMFunctions[1]) (); // Call the appropriate menu function
- break;
- case '2':
- (*FMFunctions[2]) (); // Call the appropriate menu function
- break;
- case '3':
- (*FMFunctions[3]) (); // Call the appropriate menu function
- break;
- default:
- break;
- }
- }
- }
-
- void DisplayMenu()
- {
- int c;
- Coords *p = new Coords(0, 0);
-
- while(1) {
- p->SetXY(0, 0);
- p->SetX(terminal->Center(DMTitle));
- p->SetY(terminal->ScreenCenter(DMSelections));
- terminal->ClearScreen();
- terminal->Write(DMTitle, p->XPos(), p->YPrev());
-
- for(int i = 0; i < DMSelections; i++)
- terminal->Write(displaymenu[i], p->XPos(), p->YOffset(1));
-
- terminal->Write("Press the number of your selection >",
- p->XPos(), p->YOffset(2));
-
- c = terminal->GetChar();
- switch(tolower(c)) {
- case '0':
- (*DMFunctions[0]) (); // Call the appropriate menu function
- return;
- case '1':
- (*DMFunctions[1]) (); // Call the appropriate menu function
- break;
-
- case '2':
- (*DMFunctions[2]) (); // Call the appropriate menu function
- break;
-
- default:
- break;
- }
- }
- }
-
- void FileMenu()
- {
- int c;
- Coords *p = new Coords(0, 0);
-
- while(1) {
- p->SetXY(0, 0);
- p->SetX(terminal->Center(FOMTitle));
- p->SetY(terminal->ScreenCenter(FOMSelections));
- terminal->ClearScreen();
- terminal->Write(FOMTitle, p->XPos(), p->YPrev());
-
- for(int i = 0; i < FOMSelections; i++)
- terminal->Write(filemenu[i], p->XPos(), p->YOffset(1));
-
- terminal->Write("Press the number of your selection >",
- p->XPos(), p->YOffset(2));
-
- c = terminal->GetChar();
- switch(tolower(c)) {
- case '0':
- (*FOMFunctions[0]) (); // Call the appropriate menu function
- return;
- case '1':
- (*FOMFunctions[1]) (); // Call the appropriate menu function
- break;
-
- default:
- break;
- }
- }
- }
-
- void Exit()
- {
- // Nothing to do
- }
-
- void Return()
- {
- // Nothing to do
- }
-
- void LoadKeys(EntryKey &e)
- // Visit function used to load the btree keys into memory
- {
- InMemCopy inmemcopy(e.key, e.object_address, e.class_id);
- dllist->StoreNode(inmemcopy);
- }
-
- int LoadIndexKeys()
- {
- // Clear the doubly linked list
- dllist->Clear();
-
- BtreeWalker btw(DB->Index());
- unsigned num_objects = btw.Sort(LoadKeys);
-
- return num_objects;
- }
-
- void DisplayAll()
- {
- if(DB->RebuildIndex()) {
- terminal->Write("The index file needs to be rebuilt.", 0, 1);
- terminal->AnyKey(0, 2);
- return;
- }
-
- Grocery grocery(DB);
- Coords *p = new Coords(0, 0);
- int c;
-
- terminal->ClearScreen();
- LoadIndexKeys();
-
- dllistptr = dllist->GetFront();
- while(!dllist->IsHeader(dllistptr)) {
- terminal->ClearScreen();
- p->SetXY(0, 0); // Reset x and y positions
- grocery.ReadObject(dllistptr->Data.object_address);
- DisplayObject(grocery, p);
- terminal->Write("(C)-Change, (D)-Delete, (X)-Exit",
- p->XPos(), p->YOffset(2));
- terminal->Write(", Any other key to continue");
- c = terminal->GetChar();
- switch(tolower(c)) {
- case 'c':
- terminal->ClearScreen();
- p->SetXY(0, 0);
- ChangeObject(grocery, p);
- break;
-
- case 'd': {
- int yn = terminal->YesNo("Are you sure you want to delete (y/n)",
- p->XPos(), p->YOffset(2));
- if(!yn) break;
- grocery.DeleteObject();
- break;
- }
-
- case 'x':
- dllist->Clear();
- delete p;
- return;
-
- default:
- break;
- }
- dllistptr = dllistptr->GetNext();
- }
- }
-
- void ItemBar(Coords *p)
- {
- const char *col1 = "Name";
- const char *col2 = "Brand";
- const char *col3 = "Store";
- const char *col4 = "Price";
- const char *col5= "Qty.";
- const char *col6 = "Line Total";
-
- int x = p->XPos();
- terminal->Write(col1, p->XPos(), p->YPos());
- terminal->Write(col2, p->XOffset(StringOffset+1), p->YPos());
- terminal->Write(col3, p->XOffset(StringOffset+1), p->YPos());
- terminal->Write(col4, p->XOffset(StringOffset+1), p->YPos());
- terminal->Write(col5, p->XOffset(IntOffset+1), p->YPos());
- terminal->Write(col6, p->XOffset(IntOffset+1), p->YPos());
- terminal->MoveCursor(0, p->YOffset(1));
- int i = 0;
- while (i++ < terminal->MaxCols()-1) terminal->Write('=');
- p->YOffset(1);
- p->SetX(x);
- }
-
- void DisplayLBL()
- {
- if(DB->RebuildIndex()) {
- terminal->Write("The index file needs to be rebuilt.", 0, 1);
- terminal->AnyKey(0, 2);
- return;
- }
-
- Grocery grocery(DB);
- int c;
- unsigned count = 0;
- Coords *p = new Coords(0, 0);
- terminal->ClearScreen();
- ItemBar(p);
-
- LoadIndexKeys();
-
- dllistptr = dllist->GetFront();
- while(!dllist->IsHeader(dllistptr)) {
- // Display the first object
- grocery.ReadObject(dllistptr->Data.object_address);
- LineByLine(grocery, p);
- p->YOffset(1);
- count++;
- dllistptr = dllistptr->GetNext();
- if(count > 5) {
- terminal->Write("(X)-Exit", p->XPos(), p->YOffset(2));
- terminal->Write(", Any other key to continue");
- c = terminal->GetChar();
- switch(tolower(c)) {
- case 'x':
- dllist->Clear();
- delete p; // Free Coords pointer
- return;
-
- default:
- break;
- }
- terminal->ClearScreen();
- p->SetXY(0, 0);
- ItemBar(p);
- count = 0;
- }
- }
-
- terminal->AnyKey(p->XPos(), p->YOffset(2));
- dllist->Clear();
- delete p; // Free Coords pointer
- }
-
- void Remove()
- {
- if(!AdminRights) {
- terminal->ClearScreen();
- terminal->Write("You do not have Admin User Privileges", 0, 1);
- terminal->AnyKey(0, 2);
- return;
- }
-
- terminal->ClearScreen();
- Coords *p = new Coords(0, 0);
- char buf[KeyBuf];
- Grocery grocery(DB);
-
- terminal->Write("Enter the name of the item to delete: ",
- p->XPos(), p->YPos());
- terminal->GetString(buf);
- grocery.SetName(buf);
-
- FAU addr = grocery.FindObject();
-
- if(!addr) {
- terminal->Write("Could not find: ", p->XPos(), p->YOffset(2));
- terminal->Write(buf);
- terminal->AnyKey(p->XPos(), p->YOffset(2));
- delete p; // Free the Coord pointer
- return;
- }
- int yn = terminal->YesNo("Are you sure you want to delete (y/n)",
- p->XPos(), p->YOffset(2));
- if(!yn) {
- delete p; // Free Coord pointer
- return;
- }
-
- grocery.DeleteObject();
-
- terminal->Write("Deleted item ", p->XPos(), p->YOffset(2));
- terminal->Write(buf);
-
- terminal->AnyKey(p->XPos(), p->YOffset(2));
- delete p; // Free Coord pointer
- }
-
- void FileStats()
- {
- VBDStats(terminal, DB->OpenDatabase());
- VBDStats(terminal, DB->OpenIndexFile());
- }
-
- void Add()
- {
- if(!AdminRights) {
- terminal->ClearScreen();
- terminal->Write("You do not have Admin User Privileges", 0, 1);
- terminal->AnyKey(0, 2);
- return;
- }
-
- int r = retrys;
-
- Coords *p = new Coords(0, 0);
- char buf[KeyBuf];
- terminal->ClearScreen();
-
- while(1) {
- terminal->Write("Enter the name of item to add: ", p->XPos(), p->YPos());
- terminal->GetString(buf);
- if(!*buf) r--; else break;
- if(!r) {
- delete p;
- return;
- }
- }
-
- Grocery grocery(DB);
- UString key_buf(buf);
-
- // Remove any leading space from the key name entry
- int offset = key_buf.Find(" ");
- if(offset == 0) key_buf.DeleteAt(offset, 1);
-
- if(key_buf == "") { // Check for a key name valid input
- delete p;
- return;
- }
-
- grocery.SetName(key_buf);
- FAU addr = grocery.FindObject();
-
- if(addr) {
- terminal->Write(buf, p->XPos(), p->YOffset(2));
- terminal->Write(" entry already exists.");
- terminal->AnyKey(p->XPos(), p->YOffset(2));
- delete p; // Free Coords pointer
- return;
- }
-
- AddObject(grocery, p);
- delete p; // Free Coords pointer
- }
-
- void AddObject(Grocery &grocery, Coords *p)
- {
- char buf[KeyBuf];
- double price = 0;
- int quantity = 0;
- char purchasing = ' ';
- double total = 0;
-
- terminal->Write("Enter the brand name: ",
- p->XPos(), p->YOffset(1));
- terminal->GetString(buf);
- grocery.SetBrand(buf);
- terminal->Write("Enter the name of the store: ",
- p->XPos(), p->YOffset(1));
- terminal->GetString(buf);
- grocery.SetStore(buf);
- terminal->Write("Enter the item's price: $",
- p->XPos(), p->YOffset(1));
- price = terminal->GetFloat();
- grocery.SetPrice(price);
- terminal->Write("Enter the quantity: ", p->XPos(), p->YOffset(1));
- quantity = terminal->GetInt();
- grocery.SetQuantity(quantity);
- terminal->Write("Purchasing (y/n): ", p->XPos(), p->YOffset(1));
- if(terminal->GetYesNo()) purchasing = 'Y'; else purchasing = 'N';
- grocery.SetPurchasing(purchasing);
- FLOAT64 LineTotal = grocery.GetPrice() * grocery.GetQuantity();
- grocery.SetLineTotal(LineTotal);
- terminal->Write("Line total = $", p->XPos(), p->YOffset(1));
- terminal->Write(grocery.GetLineTotal());
-
- terminal->Write("(A)-Abort (C)-Change, Any other key to accept entry",
- p->XPos(), p->YOffset(2));
- int c = terminal->GetChar();
- switch(c) {
- case 'c': case 'C':
- terminal->ClearScreen();
- p->SetXY(0, 0);
- ChangeObject(grocery, p, 1);
- break;
- case 'a':
- return;
- default:
- break;
- }
-
- int find = 0;
- FAU addr = grocery.AddObject(find); // Write the object to the file
- if(!addr) {
- terminal->Write("Could not add item to database",
- p->XPos(), p->YOffset(2));
- terminal->AnyKey(p->XPos(), p->YOffset(2));
- return;
- }
-
- terminal->Write("Item was added to the database",
- p->XPos(), p->YOffset(2));
-
- terminal->Write("Add another (y/n)", p->XPos(), p->YOffset(2));
- if(terminal->GetYesNo()) Add(); else return;
- }
-
- void FindBy(const char *MemberName, GrocDBItem item)
- {
- Coords *p = new Coords(0, 0);
- char buf[KeyBuf];
- unsigned offset = 0;
-
- terminal->ClearScreen();
-
- Grocery grocery(DB);
-
- terminal->Write("Enter complete name or use ", p->XPos(), p->YPos());
- terminal->Write(WildCard);
- terminal->Write(" for a wild card.");
- terminal->Write(MemberName, p->XPos(), p->YOffset(2));
- terminal->Write(" -> ");
- terminal->GetString(buf);
- UString str(buf);
- offset = str.Find(WildCard, offset); // Look for wild card character
-
- if(DB->RebuildIndex()) {
- terminal->Write("The index file needs to be rebuilt.",
- p->XPos(), p->YOffset(2));
- terminal->AnyKey(p->XPos(), p->YOffset(1));
- delete p;
- return;
- }
-
- if(offset == UString::NoMatch) { // No wild cards found
- grocery.SetName(buf);
- GrocDBSearch(grocery, item, str, p);
- delete p; // Free the Coord pointer
- return;
- }
-
- GrocDBSearch(grocery, item, str, p, WildCard);
- delete p; // Free the Coord pointer
- }
-
- void FindByName()
- {
- FindBy("Item Name", NAME);
- }
-
- void FindByBrand()
- {
- FindBy("Brand Name", BRAND);
- }
-
- void FindByStore()
- {
- FindBy("Store Name", STORE);
- }
-
- void Change()
- {
- if(!AdminRights) {
- terminal->ClearScreen();
- terminal->Write("You do not have Admin User Privileges", 0, 1);
- terminal->AnyKey(0, 2);
- return;
- }
-
- Coords *p = new Coords(0, 0);
- char buf[KeyBuf];
-
- terminal->ClearScreen();
- terminal->Write("Enter name of item to change: ", p->XPos(), p->YPos());
- terminal->GetString(buf);
-
- Grocery grocery(DB);
- grocery.SetName(buf);
-
- FAU addr = grocery.FindObject();
-
- if(!addr) {
- terminal->Write("Could not find: ", p->XPos(), p->YOffset(2));
- terminal->Write(buf);
- terminal->AnyKey(p->XPos(), p->YOffset(2));
- delete p; // Free Coords pointer
- return;
- }
-
- ChangeObject(grocery, p);
- delete p; // Free Coords pointer
- }
-
- void ChangeObject(Grocery &grocery, Coords *p, int adding)
- {
- char buf[KeyBuf];
-
- // Buffer the object's data to allow changes to be canceled
- Grocery ob;
- ob.Copy(grocery);
- FAU addr;
-
- // Temp buffers used to record changes
- Price pr = 0;
- Quantity qty = 0;
- Purchasing pur = ' ';
- FLOAT64 LineTotal;
- Grocery changed(DB);
-
- char *prompt = "Press the number of your selection >";
- int c, x, y, x_prev, y_prev, x_prompt, y_prompt;
- x_prev = p->XPos(); y_prev = p->YPos();
-
- while(1) {
- p->SetXY(x_prev, y_prev);
- terminal->Write("(0) Cancel change", p->XPos(), p->YOffset(2));
- if(adding) {
- terminal->Write("(1) Item's Name = ", p->XPos(), p->YOffset(1));
- terminal->Write(grocery.GetName());
- terminal->ClearLine();
- }
- else {
- terminal->Write("(-) Item's Name = ", p->XPos(), p->YOffset(1));
- terminal->Write(grocery.GetName());
- terminal->ClearLine();
- }
- terminal->Write("(2) Brand = ", p->XPos(), p->YOffset(1));
- terminal->Write(grocery.GetBrand());
- terminal->ClearLine();
- terminal->Write("(3) Store = ", p->XPos(), p->YOffset(1));
- terminal->Write(grocery.GetStore());
- terminal->ClearLine();
- terminal->Write("(4) Price = $", p->XPos(), p->YOffset(1));
- terminal->Write(grocery.GetPrice());
- terminal->ClearLine();
- terminal->Write("(5) Quantity = ", p->XPos(), p->YOffset(1));
- terminal->Write(grocery.GetQuantity());
- terminal->ClearLine();
- terminal->Write("(6) Purchasing = ", p->XPos(), p->YOffset(1));
- terminal->Write(grocery.GetPurchasing());
- terminal->ClearLine();
- terminal->Write("(-) Total = ", p->XPos(), p->YOffset(1));
- terminal->Write(grocery.GetLineTotal());
- terminal->ClearLine();
- terminal->Write("(A) Accept changes", p->XPos(), p->YOffset(1));
-
- terminal->Write(prompt, p->XPos(), p->YOffset(2));
- x_prompt = p->XPos() + strlen(prompt);
- y_prompt = p->YPos();
-
- x = p->XPos();
- y = p->YPos() + 2;
-
- c = terminal->GetChar();
- switch(tolower(c)) {
- case '0':
- grocery.Copy(ob);
- return;
-
- case '1':
- // User not allowed to change name unless adding a new object
- if(!adding) break;
- terminal->Write("Enter new name: ", x, y);
- terminal->GetString(buf);
- grocery.SetName(buf);
- if(grocery.FindObject()) {
- terminal->Write("Item already exists", x, y+1);
- terminal->AnyKey();
- terminal->ClearLine(x, y+1);
- terminal->ClearLine(x, y);
- terminal->MoveCursor(x_prev, y_prev);
- break;
- }
- terminal->ClearLine(x, y);
- terminal->MoveCursor(x_prev, y_prev);
- break;
-
- case '2':
- terminal->Write("Enter new brand: ", x, y);
- terminal->GetString(buf);
- grocery.SetBrand(buf);
- terminal->ClearLine(x, y);
- terminal->MoveCursor(x_prev, y_prev);
- break;
-
- case '3':
- terminal->Write("Enter new store: ", x, y);
- terminal->GetString(buf);
- grocery.SetStore(buf);
- terminal->ClearLine(x, y);
- terminal->MoveCursor(x_prev, y_prev);
- break;
-
- case '4':
- terminal->Write("Enter new price: $", x, y);
- pr = terminal->GetFloat();
- grocery.SetPrice(pr);
- terminal->ClearLine(x, y);
- terminal->MoveCursor(x_prev, y_prev);
- LineTotal = grocery.GetPrice() * grocery.GetQuantity();
- grocery.SetLineTotal(LineTotal);
- break;
-
- case '5':
- terminal->Write("Enter new quantity: ", x, y);
- qty = terminal->GetInt();
- grocery.SetQuantity(qty);
- terminal->ClearLine(x, y);
- terminal->MoveCursor(x_prev, y_prev);
- LineTotal = grocery.GetPrice() * grocery.GetQuantity();
- grocery.SetLineTotal(LineTotal);
- break;
-
- case '6':
- terminal->Write("Purchasing (y/n): ", x, y);
- if(terminal->GetYesNo()) pur = 'Y'; else pur = 'N';
- grocery.SetPurchasing(pur);
- terminal->ClearLine(x, y);
- terminal->MoveCursor(x_prev, y_prev);
- break;
-
- case '7':
- break;
-
- case 'A': case 'a':
- if(adding) return; // New object, no need to reallocate space
- if(grocery.FullCompare(ob)) return; // The object has not changed
- changed.Copy(grocery); // Make a copy of the changes
-
- // Remove the original object
- grocery.DeleteObject();
- changed.AddObject(0); // Add the changed object back to the database
- return;
-
- default:
- break;
- }
- }
- }
-
- void DisplayObject(Grocery &grocery, Coords *p)
- // Display's the complete object with all details.
- {
- terminal->Write("Item's Name = ", p->XPos(), p->YPos());
- terminal->Write(grocery.GetName());
- terminal->Write("Brand = ", p->XPos(), p->YOffset(1));
- terminal->Write(grocery.GetBrand());
- terminal->Write("Store = ", p->XPos(), p->YOffset(1));
- terminal->Write(grocery.GetStore());
- terminal->Write("Price = $", p->XPos(), p->YOffset(1));
- terminal->Write(grocery.GetPrice());
- terminal->Write("Quantity = ", p->XPos(), p->YOffset(1));
- terminal->Write(grocery.GetQuantity());
- terminal->Write("Purchasing = ", p->XPos(), p->YOffset(1));
- terminal->Write(grocery.GetPurchasing());
- terminal->Write("Line total = ", p->XPos(), p->YOffset(1));
- terminal->Write(grocery.GetLineTotal());
- }
-
- void DisplayString(const char *s)
- {
- int len = strlen(s);
- int offset = StringOffset;
- char *buf = new char[len + 1];
- buf[len] = '\0';
- strcpy(buf, s);
- if(len < StringOffset) offset = len;
- for(int i = 0; i < offset; i++)
- terminal->Write(buf[i]);
- delete[] buf;
- }
-
- void LineByLine(Grocery &grocery, Coords *p)
- // Display objects line by line with partial details
- {
- int x = p->XPos();
-
- terminal->MoveCursor(p->XPos(), p->YPos());
- DisplayString(grocery.GetName());
- terminal->MoveCursor(p->XOffset(StringOffset+1), p->YPos());
- DisplayString(grocery.GetBrand());
- terminal->MoveCursor(p->XOffset(StringOffset+1), p->YPos());
- DisplayString(grocery.GetStore());
- terminal->MoveCursor(p->XOffset(StringOffset+1), p->YPos());
- terminal->Write(grocery.GetPrice());
- terminal->MoveCursor(p->XOffset(IntOffset+1), p->YPos());
- terminal->Write(grocery.GetQuantity());
- terminal->MoveCursor(p->XOffset(IntOffset+1), p->YPos());
- terminal->Write(grocery.GetLineTotal());
- int i = 0;
- terminal->MoveCursor(0, p->YOffset(1));
- while (i++ < terminal->MaxCols()-1) terminal->Write('-');
- p->SetX(x);
- }
-
- void Version()
- {
- printf("\n%s program version %.3f\n", ProgramName, VersionNumber);
- exit(0);
- }
-
- void GrocDBSearch(Grocery &grocery, GrocDBItem item, UString &str,
- Coords *p, const char *wildcard)
- {
- terminal->Write("Searching for ", p->XPos(), p->YOffset(2));
- terminal->Write(str.c_str());
-
- int offset;
- offset = ObjectsFound = 0;
-
- if(wildcard != 0) {
- while(1) { // Remove the wild card characters from the string
- offset = str.Find(wildcard, offset);
- if (offset == UString::NoMatch) break;
- str.DeleteAt(offset, strlen(wildcard));
- offset++;
- }
- }
-
- // stay in sync during multiple file access.
- DB->Index()->TestTree();
-
- dllist->Clear();
-
- if(wildcard != 0)
- BtreeSearch(DB->Index(), item, grocery, str, 1);
- else
- BtreeSearch(DB->Index(), item, grocery, str);
-
- if(ObjectsFound == 0) {
- terminal->Write("No matches found.", p->XPos(), p->YOffset(2));
- terminal->AnyKey(p->XPos(), p->YOffset(1));
- return;
- }
-
- if(ObjectsFound > 1) { // Found multiple matches
- terminal->Write("Found ", p->XPos(), p->YOffset(2));
- terminal->Write(ObjectsFound);
- terminal->Write(" matching.");
- terminal->AnyKey(p->XPos(), p->YOffset(1));
- }
- else {
- terminal->Write("Found matching entry for: ", p->XPos(), p->YOffset(2));
- terminal->Write(str.c_str());
- terminal->AnyKey(p->XPos(), p->YOffset(1));
- }
-
- // Display all the matches
- dllistptr = dllist->GetFront();
- while(!dllist->IsHeader(dllistptr)) {
- terminal->ClearScreen();
- p->SetXY(0, 0);
- grocery.ReadObject(dllistptr->Data.object_address);
- DisplayObject(grocery, p);
- terminal->Write("(C)-Change, (D)-Delete, (X)-Exit",
- p->XPos(), p->YOffset(2));
- terminal->Write(", Any other key to continue");
- int c = terminal->GetChar();
- switch(c) {
- case 'c': case 'C':
- terminal->ClearScreen();
- p->SetXY(0, 0);
- grocery.ReadObject(dllistptr->Data.object_address);
- ChangeObject(grocery, p);
- break;
-
- case 'd': case 'D': {
- int yn = terminal->YesNo("Are you sure you want to delete (y/n)",
- p->XPos(), p->YOffset(2));
- if(!yn) break;
- grocery.ReadObject(dllistptr->Data.object_address);
- grocery.DeleteObject();
- break;
- }
-
- case 'x': case 'X':
- dllist->Clear(); // Free dllist memory
- return;
-
- default:
- break;
- }
- dllistptr = dllistptr->GetNext();
- }
- dllist->Clear(); // Free dllist memory
- }
-
- int main(int argc, char **argv)
- {
- // Display the program version information and exit the program
- if(argc >= 2) {
- if(strcmp(argv[1], "version") == 0) Version();
- }
-
- char *FileName;
- char *CurrentCfgFile;
- char *CfgFile;
-
- Config *CfgData = new Config;
- char *AdminUser = 0;
-
- // Look for CfgFile name in environment
- if((CurrentCfgFile = getenv("GDBCFG")) == 0)
- CfgFile = (char *)DefaultCfgFile;
- else
- CfgFile = CurrentCfgFile;
-
- // Use default file of CFG file name if no file is specifed on
- if(argc < 2) {
- int FileStatus = CfgData->Load((char *)CfgFile);
- if(!FileStatus)
- FileName = (char *)DefaultDBFileName;
- else {
- FileName = CfgData->GetStrValue("DBFileName");
- AdminUser = CfgData->GetStrValue("AdminUser");
- if(!FileName) {
- printf("\nDBFileName section missing in config file: %s\n", CfgFile);
- exit(0);
- }
- }
- }
- else {
- FileName = argv[1];
- }
-
- if(!AdminUser) {
- AdminRights = 1;
- }
- else {
- int result = strcmp(AdminUser, "FALSE");
- if(result == 0) {
- AdminRights = 0;
- }
- else {
- AdminRights = 1;
- }
- }
-
- CfgData->UnLoad(); // Unload the Config file from memory
-
- // Initialize global database pointer
- // NOTE: Index file and data file will share the same file name
- // with different file extensions. The data file will have a
- // .pod extension and the index file will have a .btx extension.
- if(AdminRights == 1)
- DB = new POD(FileName, RWMode, 1, CacheSize);
- else
- DB = new POD(FileName, ROMode, 1, CacheSize);
-
- terminal->init();
- MainMenu();
- terminal->finish();
- delete DB;
- return 0;
- }
- // ----------------------------------------------------------- //
- // ------------------------------- //
- // --------- End of File --------- //
- // ------------------------------- //
-